use super::common::*;

/// 查询某日是星期几, 如1就是周一.
/// 注: 1970-01-01 是周四
fn get_weekday(y: u32, m: u32, d: u32) -> u32 {
    let days = days_since_origin(y, m, d);
    (days + 3) % 7 + 1
}

/// 查询在指定年中第一周的星期一在此年的日偏移.
/// 1表示其为一月一日.
/// 可能为非正数, 即在去年.
fn get_week1_start(y: u32) -> i32 {
    // 1月4日是周几
    let jan4_weekday = get_weekday(y, 1, 4);
    5 - jan4_weekday as i32
}

/// 计算指定日期是哪一年的第几周. 遵循 ISO 8601.
pub fn cal_week_count(y: u32, m: u32, d: u32) -> (u32, u32) {
    let week1_start = get_week1_start(y);

    // 当前日期在今年的日偏移
    let passed_days = days_since_origin(y, m, d) - days_since_origin(y, 1, 1) + 1;

    // 属于上一年的最后一周
    if (passed_days as i32) < week1_start {
        let prev_year = y - 1;
        let prev_week1_start = get_week1_start(prev_year);

        // 年日数 + 偏差日数
        let prev_year_days = get_days_in_year(y);
        let days_from_prev_week1 =
            (prev_year_days as i32 + passed_days as i32 - prev_week1_start) as u32;

        let week_cnt = days_from_prev_week1 / 7 + 1;
        return (prev_year, week_cnt);
    }

    let days_from_week1: u32 = (passed_days as i32 - week1_start) as u32;
    let week_cnt = days_from_week1 / 7 + 1;

    // 有可能划入下一年
    if week_cnt >= 52 {
        let next_week1_start = get_week1_start(y + 1);
        let year_days = get_days_in_year(y);
        // 明年第一周在今年的日偏移
        let next_week1_start_from_curr = (year_days as i32 + next_week1_start) as u32;
        // println!("year: {}, next_week1_start: {}", y + 1, next_week1_start);
        if passed_days > next_week1_start_from_curr {
            // 属于下一年的第一周
            return (y + 1, 1);
        }
    }

    (y, week_cnt)
}

// mod tests {
//     #[allow(unused_imports)]
//     use super::*;

//     #[test]
//     fn try_count() {
//         let test_cases = vec![
//             (2023, 1, 1),   // 2022 52
//             (2023, 12, 31), // 2023 52
//             (2024, 1, 1),   // 2024 1
//             (2024, 12, 31), // 2025 1
//         ];

//         for (y, m, d) in test_cases {
//             let (belong_year, week_cnt) = cal_week_count(y, m, d);
//             println!(
//                 "{}-{:02}-{:02} is year {} week {}",
//                 y, m, d, belong_year, week_cnt
//             );
//         }
//     }

//     #[test]
//     fn test_count() {
//         let test_cases = vec![
//             ((2024, 11, 10), 45),
//             ((2024, 11, 18), 47),
//             ((2024, 12, 31), 1),
//             ((2025, 01, 01), 1),
//             ((2025, 12, 31), 1),
//             ((2020, 01, 20), 4),
//             ((2021, 02, 13), 6),
//             ((2012, 01, 22), 3),
//             ((2013, 02, 11), 7),
//             ((2014, 02, 02), 5),
//         ];

//         for ((y, m, d), ans) in test_cases {
//             let (_, week_cnt) = cal_week_count(y, m, d);
//             assert_eq!(week_cnt, ans, "WA at {:?}", (y, m, d));
//         }
//     }
// }
